package com.tc.msg.protocol;

import com.tc.msg.message.Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;

/**
 * @Auther: tianchao
 * @Date: 2022/2/14 15:35
 * @Description:
 */
@ChannelHandler.Sharable
@Slf4j
public class MessageCodeCSharable extends MessageToMessageCodec<ByteBuf, Message> {
    /**
     * @param ctx
     * @param msg
     * @param outList
     * @see io.netty.handler.codec.MessageToMessageEncoder#encode(ChannelHandlerContext, Object, List)
     */
    @Override
    protected void encode(ChannelHandlerContext ctx, Message msg, List<Object> outList) throws Exception {
        ByteBuf out = ctx.alloc().buffer();
        //1. 4字节的魔数
        out.writeBytes(new byte[]{1,2,3,4});
        //2. 1字节的版本
        out.writeByte(1);
        //3 1字节的序列化方式 jdk 0 json 1
        out.writeByte(0);
        //4 1字节指令类型
        out.writeByte(msg.getMessageType());
        //5 请求序号 4字节
        out.writeInt(msg.getSequenceId());
        out.writeByte(0xf1);
        // 6和7准备
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(msg);
        byte[] bytes = bos.toByteArray();
        //6 正文长度
        out.writeInt(bytes.length);
        //7 获取内容的字节数组
        out.writeBytes(bytes);
        //传给下一个handler
        outList.add(out);
    }

    /**
     * @param ctx
     * @param in
     * @param out
     * @see io.netty.handler.codec.MessageToMessageDecoder#decode(ChannelHandlerContext, Object, List)
     */
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        int magicNumber = in.readInt();
        byte version = in.readByte();
        byte serializerType = in.readByte();
        byte messageType = in.readByte();
        int sequenceId = in.readInt();
        final byte b = in.readByte();
        log.debug("占位字节:{}",b);
        int length = in.readInt();
        byte[] bytes = new byte[length];
        in.readBytes(bytes,0,length);
        if (serializerType == 0) {
            ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
            Object o = ois.readObject();
            Message message = (Message) o;
            out.add(message);
            log.debug("{},{},{},{},{},{}",magicNumber,version,serializerType,messageType,sequenceId,length);
            log.debug("对象：{}",message);
            System.err.println(message);
        }
    }
}
